
#include <linux/init.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/gpio.h>
#include <mach/platform.h>
#include <linux/sched.h>
#include <linux/miscdevice.h>
#include <linux/uaccess.h>
#include <linux/fs.h>
wait_queue_head_t hcsr_wqh;
char someone = -1;
volatile unsigned int ev_someone=0;
irqreturn_t hcsr_isr(int irqnum,void *dev){
    int stat=0;
    stat=gpio_get_value(PAD_GPIO_B+10);
    someone=stat;
    ev_someone=1;
    wake_up_interruptible(&hcsr_wqh);
    return IRQ_HANDLED;
}

ssize_t hcsr_read(struct file *filp,char __user *buf,size_t len, loff_t *offset){
    int ret=0;
    wait_event_interruptible(hcsr_wqh,ev_someone);

    ret=copy_to_user(buf,&someone,len);

    ev_someone=0;

    return len;
}

struct file_operations hcsr_fops = {
    .owner = THIS_MODULE,
    .read  = hcsr_read,
};

struct miscdevice hcsr_misc = {
    .name  = "hcsr",
    .minor = MISC_DYNAMIC_MINOR,
    .fops  = &hcsr_fops,
};

static int __init sr501_drv_init(void){
    int ret=request_irq(IRQ_GPIO_B_START+10,hcsr_isr,
    IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING,
    "hc-sr501",NULL);
    if(ret<0){
            printk("<1>" "request irq failed\n");
            return -EAGAIN;
        }
    misc_register(&hcsr_misc);
    init_waitqueue_head(&hcsr_wqh);
    return 0;
}

static void __exit sr501_drv_exit(void){
        free_irq(IRQ_GPIO_B_START+10,NULL);
        misc_deregister(&hcsr_misc);
    }
module_init(sr501_drv_init);
module_exit(sr501_drv_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("SGY");
